//------------------------------------------------------------------------------
// <copyright company="Telligent Systems">
//     Copyright (c) Telligent Systems Corporation.  All rights reserved.
// </copyright> 
//------------------------------------------------------------------------------

using System;
using System.Collections;


namespace CommunityServer.Components {

	/// <summary>
	/// Manages the LinkCategories in the application
	/// </summary>
	public class LinkCategories {
		private LinkCategories() {
			// static class
		}

		#region Management

		private static void Format(LinkCategory category)
		{

			if(CSContext.Current.SiteSettings.EnableCensorship)
			{
				category.Name = Transforms.CensorPost(category.Name);
				category.Description = Transforms.CensorPost(category.Description);
			}
				
			category.Name = Globals.HtmlEncode(category.Name);
			category.Description = HtmlScrubber.Clean(category.Description,true,true);
		}

		/// <summary>
		/// Adds the given link category to the database.
		/// </summary>
		public static int CreateCategory( LinkCategory category ) {

			Format(category);

		    CommonDataProvider dp = CommonDataProvider.Instance();
			category.LinkCategoryID = dp.CreateLinkCategory( category );

			// Make sure the addition was successful
			if( category.LinkCategoryID > 0 ) {
				Hashtable categories = CSCache.Get( CacheKey( category.SectionID ) ) as Hashtable;
				if( categories != null ) {
					categories.Add( category.LinkCategoryID, category );
				}
			} else {
				throw new CSException( CSExceptionType.UnknownError );
			}

            return category.LinkCategoryID;
		}
		
		/// <summary>
		/// Updates the given link category to the database.
		/// </summary>
		public static void UpdateCategory( LinkCategory category ) {
		    
			Format(category);

			CommonDataProvider dp = CommonDataProvider.Instance();
			dp.UpdateLinkCategory( category );

			Hashtable categories = CSCache.Get( CacheKey( category.SectionID ) ) as Hashtable;
			if( categories != null ) {
				if(categories.ContainsKey( category.LinkCategoryID ) ) {
					try {
						categories[ category.LinkCategoryID ] = category;
					}
					catch{}//not much to do here
				}

			}
		}

		/// <summary>
		/// Deletes the link category in the database with the given category and section ids.
		/// </summary>
		public static void DeleteCategory( Int32 categoryID, Int32 sectionID ) {
		    CommonDataProvider dp = CommonDataProvider.Instance();
			dp.DeleteLinkCategory( categoryID, sectionID );
			CSCache.Remove( CacheKey( sectionID ) );
		}
		
		/// <summary>
		/// Moves the link category up or down in a sorted list of the categories.
		/// </summary>
		public static void ChangeCategorySortOrder( Int32 linkCategoryID, Int32 sectionID, Boolean moveUp ) {
		    CommonDataProvider dp = CommonDataProvider.Instance();
			dp.ChangeLinkCategorySortOrder( linkCategoryID, moveUp );
			CSCache.Remove( CacheKey( sectionID ) );
		}

		#endregion

		#region Single Selection

		/// <summary>
		/// Gets the link category with the given category and section ids.
		/// </summary>
		public static LinkCategory GetCategory( Int32 categoryID, Int32 sectionID ) {
			return GetCategory( categoryID, sectionID, false );
		}

		/// <summary>
		/// Gets the link category with the given category and section ids.
		/// </summary>
		public static LinkCategory GetCategory( Int32 categoryID, Int32 sectionID, Boolean allowDisabled ) {
			Hashtable categories = GetCategories( sectionID, CSContext.Current, true, allowDisabled, false );
			if( !categories.Contains( categoryID ) ) {
				throw new CSException( CSExceptionType.ResourceNotFound, "Link Category not found: " + categoryID );
			}
			return (LinkCategory)categories[ categoryID ];
		}

		#endregion

		#region Multiple Selection
 
		/// <summary>
		/// Gets all the enabled link categories in the given forum.
		/// </summary>
		public static ArrayList GetCategories( Int32 sectionID ) {
			return GetCategories( sectionID, false, true );
		}


		/// <summary>
		/// Gets all the link categories in the given forum.
		/// </summary>
		public static ArrayList GetCategories( Int32 sectionID, Boolean allowDisabled ) {
			return GetCategories( sectionID, allowDisabled, true );
		}


		/// <summary>
		/// Gets all the link categories in the given forum.
		/// </summary>
		public static ArrayList GetCategories( Int32 sectionID, Boolean allowDisabled, Boolean cacheable ) 
		{
			return GetCategories( sectionID, allowDisabled, cacheable, false );
		}

			/// <summary>
		/// Gets all the link categories in the given forum.
		/// </summary>
		public static ArrayList GetCategories( Int32 sectionID, Boolean allowDisabled, Boolean cacheable, Boolean preloadLinks ) 
		{
		    CSContext csContext = CSContext.Current;
			ArrayList categories = new ArrayList();

			// Get the Albums as a hashtable
			Hashtable categoryTable = GetCategories( sectionID, csContext, allowDisabled, cacheable, preloadLinks );

			// Convert the hashtable to an arraylist
			foreach( LinkCategory category in categoryTable.Values ) {
				categories.Add( category );
			}

			// Sort the categories
			categories.Sort();

			return categories;
		}

		public static Hashtable GetCategories( Int32 sectionID, CSContext csContext, Boolean allowDisabled, Boolean cacheable, Boolean preloadLinks ) {

			string cacheKey = CacheKey( sectionID, preloadLinks );

			#if DEBUG_NOCACHE
				cacheable = false;
			#endif

			Hashtable categories = CSCache.Get( cacheKey ) as Hashtable;


			// Ensure it's not in the cache
			if( !cacheable && categories != null ) {
				CSCache.Remove( cacheKey );
			}

			// Get the categories
			if( categories == null ) {
			    CommonDataProvider dp = CommonDataProvider.Instance();

				categories =  dp.GetLinkCategories( sectionID, preloadLinks );

				// Cache if we can
				if( cacheable ) 
				{
					CSCache.Insert( cacheKey, categories, 15 * CSCache.MinuteFactor );
				}
			} 


			// Should we return all of them?
			if( allowDisabled ) {
				return categories;
			}
			
			// Filter out the disabled categories
			Hashtable enabledCategories = new Hashtable();
			foreach( LinkCategory category in categories.Values ) {
				if( category.IsEnabled ) {
					enabledCategories.Add( category.LinkCategoryID, category );
				}
			}
			return enabledCategories;
		}

		#endregion

		private static string CacheKey( Int32 sectionID ) {
			return CacheKey(sectionID, false);
		}

		private static string CacheKey( Int32 sectionID, Boolean preloadLinks ) 
		{
			if (preloadLinks)
				return String.Format( "LinkCategoriesWithLinksCacheKey:{0}", sectionID );
			else
				return String.Format( "LinkCategoriesCacheKey:{0}", sectionID );
		}

	}
}
